<article id="wikiArticle">
<div></div>
<p><code><strong>map()</strong></code> 方法创建一个新数组，其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。</p>
<div><iframe class="interactive interactive-js" frameborder="0" height="250" src="https://interactive-examples.mdn.mozilla.net/pages/js/array-map.html" width="100%"></iframe></div>
<p class="hidden">The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone <a class="external" href="https://github.com/mdn/interactive-examples" rel="noopener">https://github.com/mdn/interactive-examples</a> and send us a pull request.</p>
<h2 id="Syntax" name="Syntax">语法</h2>
<pre><var>var new_array = arr</var>.map(function <var>callback(currentValue[, index[, array]]) {
 // Return element for new_array </var>
<var>}</var>[, <var>thisArg</var>])</code></pre>
<h3 id="Parameters" name="Parameters">参数</h3>
<dl>
<dt><code>callback</code></dt>
<dd>生成新数组元素的函数，使用三个参数：
 <dl>
<dt><code>currentValue</code></dt>
<dd><code>callback</code> 数组中正在处理的当前元素。</dd>
<dt><code>index</code><span class="inlineIndicator optional optionalInline">可选</span></dt>
<dd><code>callback</code> 数组中正在处理的当前元素的索引。</dd>
<dt><code>array</code><span class="inlineIndicator optional optionalInline">可选</span></dt>
<dd><code>callback</code>  <code>map</code> 方法被调用的数组。</dd>
</dl>
</dd>
<dt><code>thisArg</code><span class="inlineIndicator optional optionalInline">可选</span></dt>
<dd>执行 <code>callback</code> 函数时使用的<code>this</code> 值。</dd>
</dl>
<h3 id="返回值">返回值</h3>
<p>一个新数组，每个元素都是回调函数的结果。</p>
<h2 id="Description" name="Description">描述</h2>
<p><code>map</code> 方法会给原数组中的每个元素都按顺序调用一次  <code>callback</code> 函数。<code>callback</code> 每次执行后的返回值（包括 <a href="Reference/Global_Objects/undefined" title="undefined是全局对象的一个属性。也就是说，它是全局作用域的一个变量。undefined的最初值就是原始数据类型undefined。"><code>undefined</code></a>）组合起来形成一个新数组。 <code>callback</code> 函数只会在有值的索引上被调用；那些从来没被赋过值或者使用 <code>delete</code> 删除的索引则不会被调用。</p>
<p><code>callback</code> 函数会被自动传入三个参数：数组元素，元素索引，原数组本身。</p>
<p>如果 <code>thisArg</code> 参数有值，则每次 <code>callback</code> 函数被调用的时候，<code>this</code> 都会指向 <code>thisArg</code> 参数上的这个对象。如果省略了 <code>thisArg </code><code>参数,</code><code>或者赋值为 null</code> 或 <code>undefined</code>，则 this 指向全局对象 。</p>
<p><code>map </code>不修改调用它的原数组本身（当然可以在 <code>callback</code> 执行时改变原数组）。</p>
<p>使用 map 方法处理数组时，数组元素的范围是在 callback 方法第一次调用之前就已经确定了。在 map 方法执行的过程中：原数组中新增加的元素将不会被 callback 访问到；若已经存在的元素被改变或删除了，则它们的传递到 callback 的值是 map 方法遍历到它们的那一时刻的值；而被删除的元素将不会被访问到。</p>
<h2 id="Examples" name="Examples">示例</h2>
<h3 id="Example:_Mapping_an_array_of_numbers_to_an_array_of_square_roots" name="Example:_Mapping_an_array_of_numbers_to_an_array_of_square_roots">求数组中每个元素的平方根</h3>
<p>下面的代码创建了一个新数组，值为原数组中对应数字的平方根。</p>
<pre><code  class="language-javascript">var numbers = [1, 4, 9];
var roots = numbers.map(Math.sqrt);
// roots的值为[1, 2, 3], numbers的值仍为[1, 4, 9]</code></pre>
<h3 id="使用_map_重新格式化数组中的对象">使用 map 重新格式化数组中的对象</h3>
<p>以下代码使用一个包含对象的数组来重新创建一个格式化后的数组。</p>
<pre><code  class="language-javascript">var kvArray = [{key: 1, value: 10}, 
               {key: 2, value: 20}, 
               {key: 3, value: 30}];

var reformattedArray = kvArray.map(function(obj) { 
   var rObj = {};
   rObj[obj.key] = obj.value;
   return rObj;
});

// reformattedArray 数组为： [{1: 10}, {2: 20}, {3: 30}], 

// kvArray 数组未被修改: 
// [{key: 1, value: 10}, 
//  {key: 2, value: 20}, 
//  {key: 3, value: 30}]
</code></pre>
<h3 id="Example:_Pluralizing_the_words_.28strings.29_in_an_array" name="Example:_Pluralizing_the_words_.28strings.29_in_an_array">使用一个包含一个参数的函数来mapping(构建)一个数字数组</h3>
<p>下面的代码表示了当函数需要一个参数时map的工作方式。当map循环遍历原始数组时，这个参数会自动被分配成数组中对应的每个元素。</p>
<pre><code  class="language-javascript">var numbers = [1, 4, 9];
var doubles = numbers.map(function(num) {
  return num * 2;
});

// doubles数组的值为： [2, 8, 18]
// numbers数组未被修改： [1, 4, 9]</code></pre>
<h3 id="Example:_using_map_generically" name="Example:_using_map_generically">一般的<code>map</code> 方法</h3>
<p>下面的例子演示如何在一个 <a href="Reference/String" title="此页面仍未被本地化, 期待您的翻译!"><code>String</code></a>  上使用 map 方法获取字符串中每个字符所对应的 ASCII 码组成的数组：</p>
<pre><code  class="language-javascript">var map = Array.prototype.map
var a = map.call("Hello World", function(x) { 
  return x.charCodeAt(0); 
})
// a的值为[72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]
</code></pre>
<h3 id="querySelectorAll_应用"><code>querySelectorAll 应用</code></h3>
<p>下面代码展示了如何去遍历用 <code>querySelectorAll </code>得到的动态对象集合。在这里，我们获得了文档里所有选中的选项，并将其打印：</p>
<pre><code  class="language-javascript">var elems = document.querySelectorAll('select option:checked');
var values = Array.prototype.map.call(elems, function(obj) {
  return obj.value;
});
</code></pre>
<h3 id="使用技巧案例">使用技巧案例</h3>
<p><a class="external" href="http://www.wirfs-brock.com/allzh-cn/posts/166" rel="noopener">(原文地址)</a></p>
<p>通常情况下，<code>map</code> 方法中的 <code>callback</code> 函数只需要接受一个参数，就是正在被遍历的数组元素本身。但这并不意味着 <code>map</code> 只给 <code>callback</code> 传了一个参数。这个思维惯性可能会让我们犯一个很容易犯的错误。</p>
<pre><code  class="language-javascript">// 下面的语句返回什么呢:
["1", "2", "3"].map(parseInt);
// 你可能觉的会是[1, 2, 3]
// 但实际的结果是 [1, NaN, NaN]

// 通常使用parseInt时,只需要传递一个参数.
// 但实际上,parseInt可以有两个参数.第二个参数是进制数.
// 可以通过语句"alert(parseInt.length)===2"来验证.
// map方法在调用callback函数时,会给它传递三个参数:当前正在遍历的元素, 
// 元素索引, 原数组本身.
// 第三个参数parseInt会忽视, 但第二个参数不会,也就是说,
// parseInt把传过来的索引值当成进制数来使用.从而返回了NaN.

function returnInt(element) {
  return parseInt(element, 10);
}

['1', '2', '3'].map(returnInt); // [1, 2, 3]
// 意料之中的结果

// 也可以使用简单的箭头函数，结果同上
['1', '2', '3'].map( str =&gt; parseInt(str) );

// 一个更简单的方式:
['1', '2', '3'].map(Number); // [1, 2, 3]
// 与`parseInt` 不同，下面的结果会返回浮点数或指数:
['1.1', '2.2e2', '3e300'].map(Number); // [1.1, 220, 3e+300]
</code></pre>
<h2 id="Compatibility" name="Compatibility" style="line-height: 30px;">Polyfill</h2>
<p><code>map</code> 是在最近的 ECMA-262 标准中新添加的方法；所以一些旧版本的浏览器可能没有实现该方法。在那些没有原生支持 <code>map</code> 方法的浏览器中，你可以使用下面的 Javascript 代码来<code>实现它。</code>所使用的算法正是 ECMA-262，第 5 版规定的。假定<code style="color: inherit;">Object</code>, <code style="color: inherit;">TypeError</code>, 和 <code>Array</code> 有他们的原始值。而且 <code style="color: inherit;">callback.call</code> 的原始值也是 <code style="color: inherit;"><a href="/zh-cn/JavaScript/Reference/Global_Objects/Function/call" rel="internal" style="color: rgb(4, 121, 167);">Function.prototype.call</a></code></p>
<pre><code class="language-js" style="font-size: 14px;">// 实现 ECMA-262, Edition 5, 15.4.4.19
// 参考: <a class="external" href="http://es5.github.com/#x15.4.4.19" rel="freelink noopener">http://es5.github.com/#x15.4.4.19</a>
if (!Array.prototype.map) {
  Array.prototype.map = function(callback, thisArg) {

    var T, A, k;

    if (this == null) {
      throw new TypeError(" this is null or not defined");
    }

    // 1. 将O赋值为调用map方法的数组.
    var O = Object(this);

    // 2.将len赋值为数组O的长度.
    var len = O.length &gt;&gt;&gt; 0;

    // 3.如果callback不是函数,则抛出TypeError异常.
    if (Object.prototype.toString.call(callback) != "[object Function]") {
      throw new TypeError(callback + " is not a function");
    }

    // 4. 如果参数thisArg有值,则将T赋值为thisArg;否则T为undefined.
    if (thisArg) {
      T = thisArg;
    }

    // 5. 创建新数组A,长度为原数组O长度len
    A = new Array(len);

    // 6. 将k赋值为0
    k = 0;

    // 7. 当 k &lt; len 时,执行循环.
    while(k &lt; len) {

      var kValue, mappedValue;

      //遍历O,k为原数组索引
      if (k in O) {

        //kValue为索引k对应的值.
        kValue = O[ k ];

        // 执行callback,this指向T,参数有三个.分别是kValue:值,k:索引,O:原数组.
        mappedValue = callback.call(T, kValue, k, O);

        // 返回值添加到新数组A中.
        A[ k ] = mappedValue;
      }
      // k自增1
      k++;
    }

    // 8. 返回新数组A
    return A;
  };      
}</code></pre>
<h2 id="规范" style="margin-bottom: 20px; line-height: 30px;">规范</h2>
<table class="standard-table">
<tbody>
<tr>
<th scope="col">Specification</th>
<th scope="col">Status</th>
<th scope="col">Comment</th>
</tr>
<tr>
<td><a class="external" href="https://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.19" hreflang="en" lang="en" rel="noopener">ECMAScript 5.1 (ECMA-262)<br/><small lang="zh-CN">Array.prototype.map</small></a></td>
<td><span class="spec-Standard">Standard</span></td>
<td>Initial definition.<br/>
    Implemented in JavaScript 1.6</td>
</tr>
<tr>
<td><a class="external" href="https://www.ecma-international.org/ecma-262/6.0/#sec-array.prototype.map" hreflang="en" lang="en" rel="noopener">ECMAScript 2015 (6th Edition, ECMA-262)<br/><small lang="zh-CN">Array.prototype.map</small></a></td>
<td><span class="spec-Standard">Standard</span></td>
<td> </td>
</tr>
<tr>
<td><a class="external" href="https://tc39.github.io/ecma262/#sec-array.prototype.map" hreflang="en" lang="en" rel="noopener">ECMAScript Latest Draft (ECMA-262)<br/><small lang="zh-CN">Array.prototype.map</small></a></td>
<td><span class="spec-Draft">Draft</span></td>
<td> </td>
</tr>
</tbody>
</table>
<h2 id="浏览器兼容性">浏览器兼容性</h2>
<div>
<div class="hidden">The compatibility table in this page is generated from structured data. If you'd like to contribute to the data, please check out <a class="external" href="https://github.com/mdn/browser-compat-data" rel="noopener">https://github.com/mdn/browser-compat-data</a> and send us a pull request.</div>
<p></p><div class="bc-data"><a class="bc-github-link external" href="https://github.com/mdn/browser-compat-data" rel="noopener">Update compatibility data on GitHub</a><table class="bc-table bc-table-js"><thead><tr class="bc-platforms"><td></td><th class="bc-platform-desktop" colspan="6"><span>Desktop</span></th><th class="bc-platform-mobile" colspan="7"><span>Mobile</span></th><th class="bc-platform-server" colspan="1"><span>Server</span></th></tr><tr class="bc-browsers"><td></td><th class="bc-browser-chrome"><span class="bc-head-txt-label bc-head-icon-chrome">Chrome</span></th><th class="bc-browser-edge"><span class="bc-head-txt-label bc-head-icon-edge">Edge</span></th><th class="bc-browser-firefox"><span class="bc-head-txt-label bc-head-icon-firefox">Firefox</span></th><th class="bc-browser-ie"><span class="bc-head-txt-label bc-head-icon-ie">Internet Explorer</span></th><th class="bc-browser-opera"><span class="bc-head-txt-label bc-head-icon-opera">Opera</span></th><th class="bc-browser-safari"><span class="bc-head-txt-label bc-head-icon-safari">Safari</span></th><th class="bc-browser-webview_android"><span class="bc-head-txt-label bc-head-icon-webview_android">Android webview</span></th><th class="bc-browser-chrome_android"><span class="bc-head-txt-label bc-head-icon-chrome_android">Chrome for Android</span></th><th class="bc-browser-edge_mobile"><span class="bc-head-txt-label bc-head-icon-edge_mobile">Edge Mobile</span></th><th class="bc-browser-firefox_android"><span class="bc-head-txt-label bc-head-icon-firefox_android">Firefox for Android</span></th><th class="bc-browser-opera_android"><span class="bc-head-txt-label bc-head-icon-opera_android">Opera for Android</span></th><th class="bc-browser-safari_ios"><span class="bc-head-txt-label bc-head-icon-safari_ios">Safari on iOS</span></th><th class="bc-browser-samsunginternet_android"><span class="bc-head-txt-label bc-head-icon-samsunginternet_android">Samsung Internet</span></th><th class="bc-browser-nodejs"><span class="bc-head-txt-label bc-head-icon-nodejs">Node.js</span></th></tr></thead><tbody><tr><th scope="row"><code>map</code></th><td class="bc-supports-yes bc-browser-chrome"><span class="bc-browser-name">Chrome</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
              Yes</td><td class="bc-supports-yes bc-browser-edge"><span class="bc-browser-name">Edge</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
              12</td><td class="bc-supports-yes bc-browser-firefox"><span class="bc-browser-name">Firefox</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
              1.5</td><td class="bc-supports-yes bc-browser-ie"><span class="bc-browser-name">IE</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
              9</td><td class="bc-supports-yes bc-browser-opera"><span class="bc-browser-name">Opera</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
              Yes</td><td class="bc-supports-yes bc-browser-safari"><span class="bc-browser-name">Safari</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
              Yes</td><td class="bc-supports-yes bc-browser-webview_android"><span class="bc-browser-name">WebView Android</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
              Yes</td><td class="bc-supports-yes bc-browser-chrome_android"><span class="bc-browser-name">Chrome Android</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
              Yes</td><td class="bc-supports-yes bc-browser-edge_mobile"><span class="bc-browser-name">Edge Mobile</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
              Yes</td><td class="bc-supports-yes bc-browser-firefox_android"><span class="bc-browser-name">Firefox Android</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
              4</td><td class="bc-supports-yes bc-browser-opera_android"><span class="bc-browser-name">Opera Android</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
              Yes</td><td class="bc-supports-yes bc-browser-safari_ios"><span class="bc-browser-name">Safari iOS</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
              Yes</td><td class="bc-supports-yes bc-browser-samsunginternet_android"><span class="bc-browser-name">Samsung Internet Android</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
              Yes</td><td class="bc-supports-yes bc-browser-nodejs"><span class="bc-browser-name">nodejs</span><abbr class="bc-level-yes only-icon" title="Full support">
<span>Full support</span>
</abbr>
              Yes</td></tr></tbody></table><section class="bc-legend" id="sect1"><h3 class="offscreen" id="Legend">Legend</h3><dl><dt><span class="bc-supports-yes bc-supports">
<abbr class="bc-level bc-level-yes only-icon" title="Full support">
<span>Full support</span>
                  
                </abbr></span></dt><dd>Full support</dd></dl></section></div><p></p>
</div>
<h2 id="See_also" name="See_also" style="margin-bottom: 20px; line-height: 30px;">相关链接</h2>
<ul>
<li><a href="Reference/Global_Objects/Array/forEach" title="forEach() 方法对数组的每个元素执行一次提供的函数。"><code>Array.prototype.forEach()</code></a></li>
<li><a href="Reference/Map" title="此页面仍未被本地化, 期待您的翻译!"><code>Map</code></a> object</li>
<li><a href="Reference/Global_Objects/Array/from" title="Array.from() 方法从一个类似数组或可迭代对象中创建一个新的数组实例。"><code>Array.from()</code></a></li>
</ul>
</article>